import store from '@/store/index.js';
import axios from 'axios';
import tools from 'public/tools/index.js'
import url from './index';

export default class starRequest {
    constructor() {
        this.config={
            // store.state.setting.apiBaseURL http://110.40.138.207:9091/
            baseURL: store.state.setting.apiBaseURL,
            timeout: 60000, // 请求超时时间
            headers: {
                common: {
                    Accept: 'application/json'
                }
            }
        };
        this.msg={
            successMessageEN:'request success',
            successMessageCN:'请求成功',
            errorMessageEN:'request error',
            errorMessageCN:'请求失败',
        };
        this.createService();
    }
    request(api,data,msg=this.msg){
        api = typeof api === 'object' ? api : url[api]

        this.msg=tools.lodash.merge(this.msg,!!msg?msg:{});
        let newApi = tools.lodash.merge(tools.lodash.cloneDeep(api), {data});
        return this.service(newApi).then(data=>{
            return data;
        })
    }
    requestInit(api,data,msg=this.msg){
        this.msg=tools.lodash.merge(this.msg,!!msg?msg:{});
        let newApi = tools.lodash.merge(tools.lodash.cloneDeep(url[api]), {data});
        return this.serviceInit(newApi).then(data=>{
            return data;
        })
    }
    createService(){
        this.service=axios.create(this.config);
        this.setRequestInterceptor();
        this.setResponseInterceptor();
        this.serviceInit=axios.create(this.config);
        this.setRequestInterceptor(this.serviceInit,true);
        this.setResponseInterceptor(this.serviceInit,true);
    }
    setRequestInterceptor(service=this.service,init=false){
        service.interceptors.request.use(
            config => {
                // 在请求发送之前做一些处理
                const token = tools.cookies.get('token');
                // 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改
                // config.headers['X-Token'] = token;
                if(!init){
                    config.headers['token'] = token;
                }

                return config;
            },
            error => {
                // 发送失败
                console.log(error);
                Promise.reject(error);
            }
        )
    }
    setResponseInterceptor(service=this.service,init=false){
        let _this=this;
        service.interceptors.response.use(
            response => {
                // dataAxios 是 axios 返回数据中的 data
                const dataAxios = response.data;
                // 这个状态码是和后端约定的
                //const code = dataAxios.meta.status;
                const code = dataAxios.code;
                // 根据 code 进行判断
                if (code === undefined) {
                    // 如果没有 code 代表这不是项目后端开发的接口
                    return dataAxios;
                } else {
                    // 有 code 代表这是一个后端接口 可以进行进一步的判断
                    switch (code) {
                        case 200:
                            // store.dispatch('admin/notice/setSuccess',{message:{'en-US':this.msg.successMessageEN,'zh-CN':this.msg.successMessageCN}});
                            if (!!dataAxios.token && dataAxios.token !== 'undefined') {
                                return dataAxios;
                            } else {
                                return init ? dataAxios : dataAxios;
                            }
                            // return dataAxios;
                        case 401:
                            if(!store.state.setting.needSSo){
                                this.errorCreate(`[ code: 401 ] ${this.msg.errorMessageCN}: ${response.config.url}`);
                                break;
                            }else{
                                this.refLogin()
                                return Promise.reject()
                            }
                        case 411:
                            // 登录错错
                            this.errorCreate(`[ code: 411 ] ${this.msg.errorMessageCN}: ${response.config.url}`);
                            break;
                        case 500:
                            // [ 示例 ] 其它和后台约定的 code
                            this.errorCreate(`[ code: 500 ] ${this.msg.errorMessageCN}: ${response.config.url}`);
                            break;
                        case '-2':
                            // 退出登录，和后台约定的 code
                            location.href='/login';
                            break;
                        default:
                            // 不是正确的 code
                            tools.errorPrompt(dataAxios.message);
                            this.errorCreate(`${this.msg.errorMessageCN}: ${response.config.url}`);
                            break;
                    }

                    return false;
                }
            },
            error => {
                if (error && error.response) {
                    switch (error.response.status) {
                        case 400: error.message = '请求错误'; break;
                        case 401: error.message = '未授权，请登录'; break;
                        case 403: error.message = '拒绝访问'; break;
                        case 404: error.message = `请求地址出错: ${error.response.config.url}`; break;
                        case 408: error.message = '请求超时'; break;
                        case 500: error.message = '服务器内部错误'; break;
                        case 501: error.message = '服务未实现'; break;
                        case 502: error.message = '网关错误'; break;
                        case 503: error.message = '服务不可用'; break;
                        case 504: error.message = '网关超时'; break;
                        case 505: error.message = 'HTTP版本不受支持'; break;
                        default: break;
                    }
                }
                this.errorLog(error);
                return Promise.reject(error);
            }
        )
    }
    errorCreate (msg) {
        const err = new Error(msg);
        this.errorLog(err);
        throw err;
    }
    errorLog (err) {
        // 添加到日志
        // store.dispatch('admin/log/push', {
        //     message: '数据请求异常',
        //     type: 'error',
        //     meta: {
        //         error: err
        //     }
        // });
        // 打印到控制台
        if (process.env.NODE_ENV === 'development') {
            tools.log.error('>>>>>> Error >>>>>>');
            console.log(err);
        }
        // 显示提示，可配置使用 iView 的 $Message 还是 $Notice 组件来显示
        store.dispatch('admin/notice/setError',{message:{'en-US':this.msg.errorMessageEN,'zh-CN':this.msg.errorMessageCN}});
    }

    /**
     * 删除URL中指定search参数,会将参数值一起删除
     * @param {string} url 地址字符串
     * @param {array} aParam 要删除的参数key数组，如['name','age']
     * @return {string} 返回新URL字符串
     */
    ridUrlParam(url, aParam) {
        aParam.forEach(item => {
            const fromIndex = url.indexOf(`${item}=`) //必须加=号，避免参数值中包含item字符串
            if (fromIndex !== -1) {
                // 通过url特殊符号，计算出=号后面的的字符数，用于生成replace正则
                const startIndex = url.indexOf('=', fromIndex)
                const endIndex = url.indexOf('&', fromIndex)
                const hashIndex = url.indexOf('#', fromIndex)

                let reg;
                if (endIndex !== -1) { // 后面还有search参数的情况
                    const num = endIndex - startIndex
                    reg = new RegExp(`${item}=.{${num}}`)
                    url = url.replace(reg, '')
                } else if (hashIndex !== -1) { // 有hash参数的情况
                    const num = hashIndex - startIndex - 1
                    reg = new RegExp(`&?${item}=.{${num}}`)
                    url = url.replace(reg, '')
                } else { // search参数在最后或只有一个参数的情况
                    reg = new RegExp(`&?${item}=.+`)
                    url = url.replace(reg, '')
                }
            }
        });
        const noSearchParam = url.indexOf('=')
        if (noSearchParam === -1) {
            url = url.replace(/\?/, '') // 如果已经没有参数，删除？号
        }
        return url
    }
    //401后重新刷新当前登录信息
    refLogin() {
        tools.cookies.remove("token");
        //如果没有登录切url参数上没有code参数则302到supOS换取认证
        let redirectUrl = this.ridUrlParam(location.href, ['state', 'code'])
        console.log("地址：" + redirectUrl)
        window.location.href =store.state.setting.apiBaseURL+"star4.0/sso/authorize?redirect_url=" + encodeURIComponent(window.location.href)
    }
}
